#ifndef __DRIVER_SERIAL_H__
#define __DRIVER_SERIAL_H__

#define BAUD_RATE_2400                  2400
#define BAUD_RATE_4800                  4800
#define BAUD_RATE_9600                  9600
#define BAUD_RATE_19200                 19200
#define BAUD_RATE_38400                 38400
#define BAUD_RATE_57600                 57600
#define BAUD_RATE_115200                115200
#define BAUD_RATE_230400                230400
#define BAUD_RATE_460800                460800
#define BAUD_RATE_921600                921600
#define BAUD_RATE_2000000               2000000
#define BAUD_RATE_3000000               3000000

#define DATA_BITS_5                     5
#define DATA_BITS_6                     6
#define DATA_BITS_7                     7
#define DATA_BITS_8                     8
#define DATA_BITS_9                     9

#define STOP_BITS_1                     0
#define STOP_BITS_2                     1
#define STOP_BITS_3                     2
#define STOP_BITS_4                     3

#define PARITY_NONE                     0
#define PARITY_ODD                      1
#define PARITY_EVEN                     2

#define FLOWCONTROL_NONE                0
#define FLOWCONTROL_RTSCTS              1

struct serial_configure {
	uint32_t baud_rate;

	uint32_t data_bits    :4;
	uint32_t stop_bits    :2;
	uint32_t parity       :2;
	uint32_t bit_order    :1;
	uint32_t invert       :1;
	uint32_t bufsz        :16;
	uint32_t flowcontrol  :1;
	uint32_t reserved     :5;
};

struct serial;

struct serial_ops {
	err_t (*configure) (struct serial *serial, struct serial_configure *configure);
	err_t (*control) (struct serial *serial, int cmd, void *arg);
	int (*putc) (struct serial *serial, char c);
	int (*getc) (struct serial *serial);

	size_t (*transmit) (struct serial *serial, uint8_t *buf, size_t size, int direction);
};

struct serial {
	struct device parent;
	struct serial_ops *ops;
	struct serial_configure *configure;

	uint8_t oflag;
};

extern err_t hw_serial_register(struct serial *serial, const char *name, void *private_data);

#endif /* __DRIVER_SERIAL_H__ */
